Release 10.1A: OpenEdge Development:
Progress 4GL Handbook
Record scope
All the elements in a Progress 4GL procedure have a scope. That is, Progress defines the portion of the application in which you can refer to the element. The buffers Progress uses for database records are no exception. In this section, you’ll look at how record scope affects statements that read database records. In Chapter 16, "Updating Your Database and Writing Triggers," you learn about how record scope affects the way you save changes back to the database within a transaction. The update-related actions include determining when in a procedure a record gets written back to the database and when it clears a record from a buffer and reads in another one. Remember that a reference to a database record is always a reference to a buffer where that record is held in memory for you, and all buffers are treated the same, whether you define them explicitly or they are provided for you by default.
There are some rules Progress uses to define just how record scope is determined. The rules might seem a bit complex at first, but they are just the result of applying some common-sense principles to the way a procedure is organized. To understand the rules, you first need to learn a few terms.
If you reference a buffer in the header of a
REPEAT FORorDO FORblock, this is called a strong-scoped reference. Any reference to the buffer within the block is a strong-scoped reference. What does this mean? The term strong-scoped means that you have made a very explicit reference to the scope of the buffer by naming it in the block header. You have told Progress that the block applies to that buffer and is being used to manage that buffer. By providing you with a buffer scoped to that block, Progress is really just following your instructions.On the other hand, if you reference a buffer in the header of a
FOR EACHorPRESELECT EACHblock, this is called a weak-scoped reference. Any reference to the buffer within the block is a weak-scoped reference.Why this difference? Keep in mind that a
REPEATblock or aDOblock does not automatically iterate through a set of records. You can execute many kinds of statements within these blocks, and if you want to retrieve a record in one of them, you have to use aFINDstatement to do it. This is why naming the buffer in the block header is called strong scoping.By contrast, a
FOR EACHblock or aPRESELECT EACHblock must name the buffers it uses, because the block automatically iterates through the set of records the block header defines. For this reason, because you really don’t have any choice except to name the buffer in the block header, Progress treats this as a weak reference. Progress recognizes that the buffer is used in that block, but it doesn’t treat it as though it can only be used within that block. You’ll see how the difference affects your procedures in the next section.The third type of buffer reference is called a free reference. Any other reference to a buffer other than the kinds already described is a free reference. Generally, this means references in
FINDstatements. These are called free references because they aren’t tied to a particular block of code. They just occur in a single statement in your procedure.The following sections describe the rules that determine how Progress treats record buffers that are used in different kinds of buffer references.
Record Buffer Rule 1: Each strong-scoped or weak-scoped reference to a buffer is self-contained.
You can combine multiple such blocks in a procedure, and each one scopes the buffer to its own block. This rule holds as long as no other reference forces the buffer to be scoped to a higher level outside these blocks. Here’s an example:
This code has two
FOR EACHblocks each with a weak-scoped reference to the Customer buffer. This is perfectly valid. First, Progress scopes the Customer buffer to the firstFOR EACHblock. When that block terminates, Progress scopes the buffer to the secondFOR EACHblock.The first block identifies the Customer with the highest CreditLimit. To do this, it sets up a
FOR EACHblock to cycle through all the Customers. The statement sorts the Customers by their CreditLimit in descending order. After it reads and displays the first of these records, the one with the highest CreditLimit, theLEAVEstatement forces the block to terminate.The qualifier
WITH 1 DOWNon theDISPLAYstatement for the first block tells Progress that it only needs to define a frame with space for one Customer. Otherwise it would allocate the entire display space. The literalHighest:makes it clear in the output what you’re looking at.The second block then independently displays all the Customers in the state of New Hampshire in order by their CreditLimit, with the highest value first. Because these two blocks occur in sequence, Progress can scope the Customer buffer to each one in turn and reuse the same Customer buffer in memory, without any conflict. That’s why this form is perfectly valid.
Figure 7–2 shows what you see when you run the procedure.
Figure 7–2: Result of record buffer Rule 1 example
![]()
|
Copyright © 2005 Progress Software Corporation www.progress.com Voice: (781) 280-4000 Fax: (781) 280-4095 |